home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / nroff / low.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  12KB  |  877 lines

  1. /*
  2.  *    low.c - misc low-level functions for nroff word processor
  3.  *
  4.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  5.  *    net:    rosenkra@hall.cray.com
  6.  *    CIS:    71460,17
  7.  *    GENIE:    W.ROSENKRANZ
  8.  *
  9.  *    original author:
  10.  *
  11.  *    Stephen L. Browning
  12.  *    5723 North Parker Avenue
  13.  *    Indianapolis, Indiana 46220
  14.  *
  15.  *    history:
  16.  *
  17.  *    - Originally written in BDS C;
  18.  *    - Adapted for standard C by W. N. Paul
  19.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  20.  *    - Adapted to have it recognize also VT100 escape codes (e.g. ESC[7m)
  21.  *      by Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
  22.  */
  23.  
  24. #undef NRO_MAIN                    /* extern globals */
  25.  
  26. #include <stdio.h>
  27. #include "nroff.h"
  28.  
  29.  
  30.  
  31. /*------------------------------*/
  32. /*    atod            */
  33. /*------------------------------*/
  34. atod (c)
  35. char    c;
  36. {
  37.  
  38. /*
  39.  *    convert ascii character to decimal.
  40.  */
  41.  
  42.     return (((c < '0') || (c > '9')) ? -1 : c - '0');
  43. }
  44.  
  45.  
  46.  
  47.  
  48.  
  49. /*------------------------------*/
  50. /*    robrk            */
  51. /*------------------------------*/
  52. robrk ()
  53. {
  54.  
  55. /*
  56.  *    end current filled line
  57.  */
  58.  
  59.     if (co.outp > 0)
  60.     {
  61. #ifdef GEMDOS
  62.         co.outbuf[co.outp]   = '\r';
  63.         co.outbuf[co.outp+1] = '\n';
  64.         co.outbuf[co.outp+2] = EOS;
  65. #else
  66.         co.outbuf[co.outp]   = '\n';
  67.         co.outbuf[co.outp+1] = EOS;
  68.         co.outbuf[co.outp+2] = EOS;
  69. #endif
  70.         put (co.outbuf);
  71.     }
  72.     co.outp   = 0;
  73.     co.outw   = 0;
  74.     co.outwds = 0;
  75.     co.outesc = 0;
  76. }
  77.  
  78.  
  79.  
  80.  
  81. /*------------------------------*/
  82. /*    ctod            */
  83. /*------------------------------*/
  84. ctod (p)
  85. register char  *p;
  86. {
  87.  
  88. /*
  89.  *    convert string to decimal.
  90.  *    processes only positive values.
  91.  */
  92.  
  93.     register int    val;
  94.     register int    d;
  95.  
  96.     val = 0;
  97.     while (*p != EOS)
  98.     {
  99.         d = atod (*p);
  100.         p++;
  101.         if (d == -1)
  102.             return (val);
  103.         val = 10 * val + d;
  104.     }
  105.     return (val);
  106. }
  107.  
  108.  
  109.  
  110.  
  111. /*------------------------------*/
  112. /*    inptobu            */
  113. /*------------------------------*/
  114. inptobu (ps)
  115. char   *ps;
  116. {
  117.  
  118. /*
  119.  *    convert input units to b.u.
  120.  */
  121.  
  122.     return;
  123. }
  124.  
  125.  
  126.  
  127.  
  128. /*------------------------------*/
  129. /*    butochar        */
  130. /*------------------------------*/
  131. butochar (ps)
  132. char   *ps;
  133. {
  134.  
  135. /*
  136.  *    convert b.u. to char spaces
  137.  */
  138.  
  139.     return;
  140. }
  141.  
  142.  
  143.  
  144.  
  145. /*------------------------------*/
  146. /*    skipbl            */
  147. /*------------------------------*/
  148. char   *skipbl (p)
  149. register char  *p;
  150. {
  151.  
  152. /*
  153.  *    skip blanks and tabs in character buffer. return ptr to first
  154.  *    non-space or non-tab char. this could mean EOS or \r or \n.
  155.  *    also increments the arg ptr (side effect).
  156.  */
  157.  
  158.     while ((*p != EOS) && (*p == ' ' || *p == '\t'))
  159.         ++p;
  160.     return (p);
  161. }
  162.  
  163.  
  164.  
  165.  
  166. /*------------------------------*/
  167. /*    skipwd            */
  168. /*------------------------------*/
  169. char   *skipwd (p)
  170. register char  *p;
  171. {
  172.  
  173. /*
  174.  *    skip over word and punctuation. anything but space,\t,\r,\n, and EOS
  175.  *    is skipped. return ptr to the first of these found. also increments
  176.  *    the arg ptr (side effect).
  177.  */
  178.  
  179.     while (*p != ' ' && *p != '\t' && *p != '\r' && *p != '\n' && *p != EOS)
  180.         ++p;
  181.     return (p);
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /*------------------------------*/
  189. /*    space            */
  190. /*------------------------------*/
  191. space (n)
  192. int     n;
  193. {
  194.  
  195. /*
  196.  *    space vertically n lines. this does header and footer also.
  197.  */
  198.  
  199.     robrk ();
  200.     if (pg.lineno > pg.bottom)
  201.         return;
  202.     if (pg.lineno == 0)
  203.         phead ();
  204.     skip (min (n, pg.bottom + 1 - pg.lineno));
  205.     pg.lineno += n;
  206.     set_ireg ("ln", pg.lineno, 0);
  207.     if (pg.lineno > pg.bottom)
  208.         pfoot ();
  209. }
  210.  
  211.  
  212.  
  213.  
  214. /*------------------------------*/
  215. /*    getfield        */
  216. /*------------------------------*/
  217. char   *getfield (p, q, delim)
  218. register char  *p;
  219. register char  *q;
  220. char        delim;
  221. {
  222.  
  223. /*
  224.  *    get field from title
  225.  */
  226.  
  227.     while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS)
  228.     {
  229.         *q++ = *p++;
  230.     }
  231.     *q = EOS;
  232.     if (*p == delim)
  233.         ++p;
  234.     return (p);
  235. }
  236.  
  237.  
  238.  
  239.  
  240.  
  241. /*------------------------------*/
  242. /*    getwrd            */
  243. /*------------------------------*/
  244. getwrd (p0, p1)
  245. register char  *p0;
  246. register char  *p1;
  247. {
  248.  
  249. /*
  250.  *    get non-blank word from p0 into p1.
  251.  *    return number of characters processed.
  252.  */
  253.  
  254.     register int    i;
  255.     register char  *p;
  256.     char        c;
  257.  
  258.     /*
  259.      *   init counter...
  260.      */
  261.     i = 0;
  262.  
  263.  
  264.     /*
  265.      *   skip leading whitespace
  266.      */
  267.     while (*p0 && (*p0 == ' ' || *p0 == '\t'))
  268.     {
  269.         ++i;
  270.         ++p0;
  271.     }
  272.  
  273.  
  274.     /*
  275.      *   set ptr and start to look for end of word
  276.      */
  277.     p = p0;
  278.     while (*p0 != ' ' && *p0 != EOS && *p0 != '\t')
  279.     {
  280.         if (*p0 == '\n' || *p0 == '\r')
  281.             break;
  282.         *p1 = *p0++;
  283.         ++p1;
  284.         ++i;
  285.     }
  286.  
  287.     c = *(p1 - 1);
  288.     if (c == '"')
  289.         c = *(p1 - 2);
  290.     if (c == '?' || c == '!')
  291.     {
  292.         *p1++ = ' ';
  293.         ++i;
  294.     }
  295.     if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower (*p)))
  296.     {
  297.         *p1++ = ' ';
  298.         ++i;
  299.     }
  300.     *p1 = EOS;
  301.  
  302.     return (i);
  303. }
  304.  
  305.  
  306.  
  307.  
  308. /*------------------------------*/
  309. /*    countesc        */
  310. /*------------------------------*/
  311.  
  312. #define ESC            27
  313.  
  314. countesc (p)
  315. register char  *p;
  316. {
  317.  
  318. /*
  319.  *    count escape sequence characters in given null-terminated
  320.  *    string
  321.  */
  322.  
  323.     register char  *pp;
  324.     register int    num;
  325.  
  326.     pp  = p;
  327.     num = 0;
  328.  
  329.     while (*pp != EOS)
  330.     {
  331.         if (*pp == ESC)
  332.         {
  333.             /*
  334.              *   count escape char (vt52 and vt100)
  335.              */
  336.             switch (*(pp+1))
  337.             {
  338.             case 'A':            /* ESC-a */
  339.             case 'B':
  340.             case 'C':
  341.             case 'D':
  342.             case 'E':
  343.             case 'H':
  344.             case 'I':
  345.             case 'J':
  346.             case 'K':
  347.             case 'L':
  348.             case 'M':
  349.             case 'd':
  350.             case 'e':
  351.             case 'f':
  352.             case 'j':
  353.             case 'k':
  354.             case 'l':
  355.             case 'o':
  356.             case 'p':
  357.             case 'q':
  358.             case 'v':
  359.             case 'w':
  360.                 num += 2;
  361.                 break;
  362.             case 'b':            /* ESC-a-b */
  363.             case 'c':
  364.                 num += 3;
  365.                 break;
  366.             case 'Y':            /* ESC-a-b-c */
  367.             case '[':            /* Esc [ 7 m */
  368.                 num += 4;
  369.                 break;
  370.             default:
  371.                 num += 1;
  372.                 break;
  373.             }
  374.         }
  375.         pp++;
  376.     }
  377.  
  378.     return (num);
  379. }
  380.  
  381.  
  382.  
  383.  
  384. /*------------------------------*/
  385. /*    itoda            */
  386. /*------------------------------*/
  387. itoda (value, p, size)
  388. int        value;
  389. register char  *p;
  390. register int    size;
  391. {
  392.  
  393. /*
  394.  *    convert integer to decimal ascii string
  395.  */
  396.  
  397.     register int    i;
  398.     register int    j;
  399.     register int    k;
  400.     register int    aval;
  401.     char        c[20];
  402.  
  403.     aval = abs (value);
  404.     c[0] = EOS;
  405.     i = 1;
  406.     do
  407.     {
  408.         c[i++] = (aval % 10) + '0';
  409.         aval /= 10;
  410.  
  411.     } while (aval > 0 && i <= size);
  412.  
  413.     if (value < 0 && i <= size)
  414.         c[i++] = '-';
  415.     for (j = 0; j < i; ++j)
  416.         *p++ = c[i - j - 1];
  417.  
  418.     return (i);
  419. }
  420.  
  421.  
  422.  
  423.  
  424. /*------------------------------*/
  425. /*    itoROMAN        */
  426. /*------------------------------*/
  427. itoROMAN (value, p, size)
  428. int        value;
  429. register char  *p;
  430. register int    size;
  431. {
  432.  
  433. /*
  434.  *    convert integer to upper roman. must be positive
  435.  */
  436.  
  437.     register int    i;
  438.     register int    j;
  439.     register int    k;
  440.     register int    aval;
  441.     char        c[100];
  442.     int        rem;
  443.  
  444.     aval = abs (value);
  445.     c[0] = EOS;
  446.     i = 1;
  447.  
  448.     /*
  449.      *   trivial case:
  450.      */
  451.     if (aval == 0)
  452.     {
  453.         c[i++] = '0';
  454.         goto done_100;
  455.     }
  456.  
  457.     /*
  458.      *   temporarily mod 100...
  459.      */
  460.     aval = aval % 100;
  461.  
  462.     if (aval > 0)
  463.     {
  464.         /*
  465.          *   build backward
  466.          *
  467.          *   | I|        1
  468.          *   | II|        2
  469.          *   | III|        3
  470.          *   | VI|        4
  471.          *   | V|        5
  472.          *   | IV|        6
  473.          *   | IIV|        7
  474.          *   | IIIV|        8
  475.          *   | XI|        9
  476.          *   | X|        0
  477.          *   | IX|        11
  478.          *   | IIX|        12
  479.          */
  480.         if ((aval % 5 == 0) && (aval % 10 != 0))/* 5 */
  481.             c[i++] = 'V';
  482.         else
  483.         {
  484.             rem = aval % 10;
  485.             if (rem == 9)            /* 9 */
  486.             {
  487.                 c[i++] = 'X';
  488.                 c[i++] = 'I';
  489.             }
  490.             else if (rem == 8)        /* 8 */
  491.             {
  492.                 c[i++] = 'I';
  493.                 c[i++] = 'I';
  494.                 c[i++] = 'I';
  495.                 c[i++] = 'V';
  496.             }
  497.             else if (rem == 7)        /* 7 */
  498.             {
  499.                 c[i++] = 'I';
  500.                 c[i++] = 'I';
  501.                 c[i++] = 'V';
  502.             }
  503.             else if (rem == 6)        /* 6 */
  504.             {
  505.                 c[i++] = 'I';
  506.                 c[i++] = 'V';
  507.             }
  508.             else if (rem == 4)        /* 4 */
  509.             {
  510.                 c[i++] = 'V';
  511.                 c[i++] = 'I';
  512.             }
  513.             else                /* 3,2,1 */
  514.             {
  515.                 for (j = 0; j < rem; j++)
  516.                     c[i++] = 'I';
  517.             }
  518.         }
  519.  
  520.         aval /= 10;
  521.         if (aval == 0)
  522.             goto done_100;
  523.  
  524.         rem = aval % 10;
  525.         if (rem == 4)
  526.         {
  527.             c[i++] = 'L';
  528.             c[i++] = 'X';
  529.         }
  530.         else if (rem == 5)
  531.         {
  532.             c[i++] = 'L';
  533.         }
  534.         else if (rem < 4)
  535.         {
  536.             for (j = 0; j < rem; j++)
  537.                 c[i++] = 'X';
  538.         }
  539.         else
  540.         {
  541.             for (j = 0; j < rem - 5; j++)
  542.                 c[i++] = 'X';
  543.             c[i++] = 'L';
  544.         }
  545.     }
  546.  
  547.  
  548. done_100:
  549.     /*
  550.      *   divide by 100 (they are done) and temp mod by another 10
  551.      */
  552.     aval  = abs (value);
  553.     aval /= 100;
  554.  
  555.     if (aval > 0)
  556.     {
  557.         rem  = aval % 10;
  558.         if (rem == 4)
  559.         {
  560.             c[i++] = 'D';
  561.             c[i++] = 'C';
  562.         }
  563.         if (rem == 5)
  564.         {
  565.             c[i++] = 'D';
  566.         }
  567.         else if (rem < 4)
  568.         {
  569.             for (j = 0; j < rem; j++)
  570.                 c[i++] = 'C';
  571.         }
  572.         else if (rem == 9)
  573.         {
  574.             c[i++] = 'M';
  575.             c[i++] = 'C';
  576.         }
  577.         else if (rem < 9)
  578.         {
  579.             for (j = 0; j < rem - 5; j++)
  580.                 c[i++] = 'C';
  581.             c[i++] = 'D';
  582.         }
  583.     }
  584.  
  585.  
  586.     aval /= 10;
  587.  
  588.     if (aval > 0)
  589.     {
  590.         rem  = aval